package cn.tedu.charging.order.quartz;

import cn.tedu.charging.order.dao.mapper.repository.OrderRepository;
import cn.tedu.charging.order.pojo.po.ChargingBillFailPO;
import cn.tedu.charging.order.pojo.po.ChargingBillSuccessPO;
import lombok.extern.slf4j.Slf4j;
import org.quartz.*;
import org.quartz.impl.StdSchedulerFactory;

import java.util.Date;
import java.util.UUID;

/**
 * @Author: Miyako
 * @Date: 2024-10-22-9:40
 * @Description:
 */
@Slf4j
public class DeviceCheckJob implements Job {

    //给反射机制使用
    public DeviceCheckJob (){
    }

    public DeviceCheckJob(String orderNo,Integer gunId) throws SchedulerException {
        log.debug("添加设备自检定时任务:订单号:{},枪id:{}",orderNo,gunId);

        //创建调度器工厂
        SchedulerFactory schedulerFactory = new StdSchedulerFactory();
        //通过调度器工厂创建调度器
        Scheduler scheduler = schedulerFactory.getScheduler();

        JobDetail jobDetail = JobBuilder.newJob(DeviceCheckJob.class)
                //定义定时任务的名称和组 作为任务的唯一标识
                .withIdentity("DeviceCheckJob" + UUID.randomUUID(),"device_check_jobs")
                //传入订单号
                .usingJobData("orderNo",orderNo)
                //传入枪id
                .usingJobData("gunId",gunId)
                .build();

        //定义任务触发的时间
        //当前时间 + 1分钟 (模拟设备自检需要1分钟)
        //当前时间
        long now = System.currentTimeMillis();
        // 1分钟
        long deviceCheckTime =  1 * 60 * 1000;
        //任务触发时间  当前时间 + 1分钟  任务会在1分钟以后执行
        Date triggerTime = new Date(now + deviceCheckTime);

        //触发器
        Trigger trigger = TriggerBuilder.newTrigger().startAt(triggerTime).build();

        //调度器scheduler  把 任务 jobDetail 和  触发器 trigger 进行绑定
        //调度器 scheduler 让任务 jobDetail 按照 时间 trigger 来触发
        scheduler.scheduleJob(jobDetail,trigger);
        //启动调用器
        scheduler.start();

    }


    /**
     * 任务执行的逻辑
     * @param context
     * @throws JobExecutionException
     */
    @Override
        public void execute(JobExecutionContext context) throws JobExecutionException {
            log.debug("设备开始自检");
        JobDataMap jobDataMap = context.getJobDetail().getJobDataMap();
        String orderNo = jobDataMap.getString("orderNo");
        Integer gunId = jobDataMap.getInt("gunId");
        //通过自定义的容器管理工具达成在非容器类中调用bean对象
        OrderRepository orderRepository = SpringContextJobUtils.getBean("OrderRepository", OrderRepository.class);

        //通过订单号获取成功订单记录
        ChargingBillSuccessPO chargingBillSuccessPO = orderRepository.getSuccessOrder(orderNo);
        //判断是否存在成功订单，保证幂等性
        if (chargingBillSuccessPO == null){
            log.debug("没有成功记录");
            //获取失败订单记录
          ChargingBillFailPO chargingBillFailPO = orderRepository.getFailOrder(orderNo);
            if (chargingBillFailPO == null){
                log.debug("（设备无响应）也没有失败记录，开始写入失败记录");
                ChargingBillFailPO newChargingBillFailPO = new ChargingBillFailPO();
                newChargingBillFailPO.setBillId(orderNo);
                newChargingBillFailPO.setGunId(gunId);
                newChargingBillFailPO.setFailDesc("设备自检失败，设备无响应");
                int row = orderRepository.saveFailOrder(newChargingBillFailPO);
                log.debug("保存失败记录：{}，{}条",newChargingBillFailPO,row);
            }else {
                log.debug("有响应.有失败记录，不能充电");
                log.debug("已记录无需处理");
            }
        }else {
            log.debug("有响应,且有成功记录");
            log.debug("更新设备信息到成功订单表:枪id:{},订单号:{},这里只是为了演示业务流程,不是必须操作",gunId,orderNo);
            int row = orderRepository.updateDeviceInfo(orderNo,gunId);
            log.debug("更新了{}条数据",row);
        }

    }
}